//
//  PilotPageViewController.m
//  EVETracker
//
//  Created by Scott Guyer on 7/16/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "PilotPageViewController.h"
#import "PilotTabViewController.h"
#import "RootPilotViewController.h"
#import "Character.h"
#import "EVEApi.h"
#import "EVEPortraitService.h"
#import "Skill.h"
#import "InventoryItem.h"
#import "EVEdb.h"
#import "AlertManager.h"
#import "defs.h"


@implementation PilotPageViewController


@synthesize idx, parentVC, rootPilotVC;
@synthesize pilotNameLabel, corpLabel, raceLabel;
@synthesize iskiesHdr, iskiesValue;
@synthesize skillpointsHdr, skillpointsValue;
@synthesize attHdr, attValue;
@synthesize progressView, trainingSkillLabel, endDateLabel;
@synthesize pilot;
// skillTrainingDict;
@synthesize reloadButton, cancelButton, skillsDetailButton, configButton;
@synthesize portraitNeedsReload, statusLine;



- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{
	if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) 
	{
		eveRequestHandle = nil;
		eveSkillsHandle = nil;
		eveImgSvc = nil;
		portraitNeedsReload = YES;
		displayRemaining = NO;
		
		NSArray* nibObjects = [[NSBundle mainBundle] loadNibNamed:nibNameOrNil owner:self options:nil];
		if ( nibObjects == nil )
		{
			NSLog(@"%s can't load nib %@", __FUNCTION__, nibNameOrNil);
			return nil;
		}
		
		UIFont* f = [[corpLabel font] fontWithSize:12.0];
		[corpLabel setFont:f];
		[raceLabel setFont:f];
		[iskiesValue setFont:f];
		[iskiesHdr setFont:f];
		[skillpointsValue setFont:f];
		[skillpointsHdr setFont:f];
		[attValue setFont:f];
		[attHdr setFont:f];
		[statusLine setFont:f];

		f = [[endDateLabel font] fontWithSize:11.0];
		[endDateLabel setFont:f];
		
		[endDateLabel setText:@""];
		[progressView setProgress:0.0];
		[endDateLabel setUserInteractionEnabled:YES];
		
		f = [UIFont boldSystemFontOfSize:16.0];
		//f = [[trainingSkillLabel font] fontWithSize:18.0];
		[trainingSkillLabel setFont:f];
		[trainingSkillLabel setText:@""];
		
		// Wire up buttons and handlers
		[reloadButton addTarget:self action:@selector(reloadHandler:) forControlEvents:UIControlEventTouchUpInside];
		[reloadButton setShowsTouchWhenHighlighted:YES];
		[cancelButton addTarget:self action:@selector(cancelHandler:) forControlEvents:UIControlEventTouchUpInside];
		[cancelButton setShowsTouchWhenHighlighted:YES];
		[configButton addTarget:self action:@selector(configHandler:) forControlEvents:UIControlEventTouchUpInside];
		[skillsDetailButton addTarget:self action:@selector(skillsHandler:) forControlEvents:UIControlEventTouchUpInside];
		
		[self enableReloadButton];
	}
	
	return self;
}


- (void) characterReplyFrom:(EVEApi*)reqHandle withResponse:(id)respObj
{	
	[eveRequestHandle release];
	eveRequestHandle = nil;

	if ( (eveSkillsHandle == nil) && (eveRequestHandle == nil) )
		[self enableReloadButton];

	if ( respObj == nil )
	{
 		[[AlertManager sharedAlertManager] alert:AlertManagerAlertType_EVEServiceUnavailable
									  withString:@"Unable to access the EVE service at this time."];
	}
	else
	{
		[pilot updateCharacterDataFrom:(Character*)respObj];
		[self reloadPilotData];
		
		NSCalendar* cal = [NSCalendar currentCalendar];
		NSDateComponents* now = [cal components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit)
									   fromDate:[NSDate date]];
		NSString* ts = [NSString stringWithFormat:@"Last updated: %.2d:%.2d:%.2d", [now hour], [now minute], [now second]];
		statusLine.text = ts;
		[skillsDetailButton setEnabled:YES];
	}
}


- (void) skillsReplyFrom:(EVEApi*)reqHandle withResponse:(id)respObj
{
	[eveSkillsHandle release];
	eveSkillsHandle = nil;

	if ( (eveSkillsHandle == nil) && (eveRequestHandle == nil) )
		[self enableReloadButton];

	if ( respObj == nil )
	{
		[[AlertManager sharedAlertManager] alert:AlertManagerAlertType_EVEServiceUnavailable
									  withString:@"Unable to access the EVE service at this time."];
	}
	else
	{
		if ( pilot.skillTrainingDict != nil )
			[pilot.skillTrainingDict release];
		
		pilot.skillTrainingDict = (NSDictionary*) respObj;
		
		if ( pilot.trainingDataLastLoad )
			[pilot.trainingDataLastLoad release];		
		NSDate* d = (NSDate*)[pilot.skillTrainingDict objectForKey:@"lastLoad"];
		pilot.trainingDataLastLoad = d;
		
		if ( pilot.trainingDataCachedUntil )
			[pilot.trainingDataCachedUntil release];
		d = (NSDate*)[pilot.skillTrainingDict objectForKey:@"cachedUntil"];
		if ( d != nil )
		{
			pilot.trainingDataCachedUntil = d;
		}
		else
		{
			pilot.trainingDataCachedUntil = nil;
		}
		
		
		[self reloadSkillData];
		
		NSCalendar* cal = [NSCalendar currentCalendar];
		NSDateComponents* now = [cal components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit)
									   fromDate:[NSDate date]];
		NSString* ts = [NSString stringWithFormat:@"Last updated: %.2d:%.2d:%.2d", [now hour], [now minute], [now second]];
		statusLine.text = ts;
		
		[rootPilotVC updateCompletedPilotsCount];
	}		
}


- (void) imageReplyFrom:(EVEPortraitService*)imgSvc withImage:(UIImage*)img
{
	[eveImgSvc release];
	eveImgSvc = nil;
	
	if ( img != nil )
	{
		portraitNeedsReload = NO;		
		[pilotPortrait setImage:img];
	}
	else
	{
		UIImage* missingImg = [UIImage imageNamed:@"missing.png"];
		[pilotPortrait setImage:missingImg];
		portraitNeedsReload = YES;	
	}
	
}



- (void) loadPortrait
{
	if ( eveImgSvc != nil )
		return;
	
	eveImgSvc = [[EVEPortraitService alloc] init];
	if ( eveImgSvc != nil )
	{
		[eveImgSvc getSmallPortrait:pilot.charID 
						  respondTo:self 
					  usingSelector:@selector(imageReplyFrom:withImage:) ];
	}	
}



- (void) reloadHandler:(id)sender
{
	BOOL uptodate = YES;
	
  	if ( eveRequestHandle == nil )
	{
		if ( (pilot.characterDataCachedUntil != nil) &&
			 ([pilot.characterDataCachedUntil compare:[NSDate date]] == NSOrderedDescending) )
		{
			NSLog(@"%s character data is already up-to-date", __FUNCTION__);
			//[[AlertManager sharedAlertManager] alert:AlertManagerAlertType_EVEDataIsCurrent
			//							  withString:@"The data as loaded is already up to date."];
		}
		else 
		{
			eveRequestHandle = [[EVEApi alloc] initWithUser:pilot.userID andKey:pilot.apiKey];
			if ( eveRequestHandle != nil )
			{
				[eveRequestHandle setResponseDelegate:self];
				[eveRequestHandle getCharacter:pilot.charID withCallback:@selector(characterReplyFrom:withResponse:)];
				[self enableCancelButton];
				statusLine.text = @"Updating ...";
				uptodate = NO;
			}
		}
	}
	
	if ( eveSkillsHandle == nil )
	{
		if ( (pilot.trainingDataCachedUntil != nil) &&
			([pilot.trainingDataCachedUntil compare:[NSDate date]] == NSOrderedDescending) )
		{
			NSLog(@"%s training data is already up-to-date", __FUNCTION__);
			//[[AlertManager sharedAlertManager] alert:AlertManagerAlertType_EVEDataIsCurrent
			//							  withString:@"The data as loaded is already up to date."];
		}
		else
		{
			eveSkillsHandle = [[EVEApi alloc] initWithUser:pilot.userID andKey:pilot.apiKey];
			if ( eveSkillsHandle != nil )
			{
				[eveSkillsHandle setResponseDelegate:self];
				[eveSkillsHandle getTrainingSkill:pilot.charID withCallback:@selector(skillsReplyFrom:withResponse:)];
				[self enableCancelButton];
				statusLine.text = @"Updating ...";
				uptodate = NO;
			}
		}
	}	
	
	if ( uptodate )
	{
		NSCalendar* cal = [NSCalendar currentCalendar];
		NSDateComponents* now = [cal components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit)
									   fromDate:[NSDate date]];
		NSString* ts = [NSString stringWithFormat:@"Last updated: %.2d:%.2d:%.2d", [now hour], [now minute], [now second]];
		statusLine.text = ts;		
	}

	if ( portraitNeedsReload )
	{
		[self loadPortrait];
	}
}


- (void) cancelHandler:(id)sender
{
	if ( eveSkillsHandle != nil )
	{
		[eveSkillsHandle cancel];
		[eveSkillsHandle release];
		eveSkillsHandle = nil;
	}
	
	if ( eveRequestHandle != nil )
	{
		[eveRequestHandle cancel];
		[eveRequestHandle release];
		eveRequestHandle = nil;
	}
	
	[self enableReloadButton];
}

- (void) configHandler:(id)sender
{
	[rootPilotVC showSettings];
}


- (void) skillsHandler:(id)sender
{
	// TODO: should probably validate that we have data to show
	[rootPilotVC showPilotSkills:pilot];
}



- (void) reloadPilotData
{
	if ( portraitNeedsReload )
	{
		[self loadPortrait];
	}
	
	NSNumberFormatter* outNf = [[NSNumberFormatter alloc] init];
	[outNf setFormatterBehavior:NSNumberFormatterBehavior10_4];
	[outNf setPositiveFormat:@"#,##0"];

	NSNumberFormatter* inNf = [[NSNumberFormatter alloc] init];
	[inNf setFormatterBehavior:NSNumberFormatterBehavior10_4];
	[inNf setPositiveFormat:@"##0.00"];
	
	NSNumber* n = [inNf numberFromString:pilot.iskies];
	NSString* formatted = [outNf stringFromNumber:n];	
	[iskiesValue setText:formatted];

	formatted = [outNf stringFromNumber:[NSNumber numberWithInt:pilot.skillPoints]];	
	[skillpointsValue setText:formatted];
	
	[inNf release];
	[outNf release];
	
	
	[pilotNameLabel setText:pilot.name];
	[corpLabel setText:pilot.corporationName];
	[raceLabel setText:[pilot getDescription]];
//	[iskiesValue setText:pilot.iskies];
//	[skillpointsValue setText:[NSString stringWithFormat:@"%d", pilot.skillPoints]];
	float i = [pilot getEffectiveAttribute:kPilotAttrTypeIntel];
	float m = [pilot getEffectiveAttribute:kPilotAttrTypeMemory];
	float c = [pilot getEffectiveAttribute:kPilotAttrTypeCharisma];
	float p = [pilot getEffectiveAttribute:kPilotAttrTypePerception];
	float w = [pilot getEffectiveAttribute:kPilotAttrTypeWillpower];
	//NSString* atts = [NSString stringWithFormat:@"I:%.1f  M:%.1f  C:%.1f  P:%.1f  W:%.1f", i, m, c, p, w];
	NSString* atts = [NSString stringWithFormat:@"I:%.1f M:%.1f C:%.1f P:%.1f W:%.1f", i, m, c, p, w];	
	[attValue setText:atts];	
}


- (void) displayEndDate
{
	NSDate* s = (NSDate*)[pilot.skillTrainingDict valueForKey:@"startDate"];
	NSDate* f = (NSDate*)[pilot.skillTrainingDict valueForKey:@"endDate"];
	if ( (s!=nil) && (f!=nil) )
	{
		NSTimeZone* zulu = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
		NSCalendar* lcal = [NSCalendar currentCalendar];
		NSCalendar* zcal = [NSCalendar currentCalendar];
		[zcal setTimeZone:zulu];
		
		NSDateComponents* comp = [lcal components:0x03ff fromDate:f];
		NSDate* lf = [zcal dateFromComponents:comp];
		
		NSTimeInterval remain = [lf timeIntervalSinceNow]; 
		NSTimeInterval total = [f timeIntervalSinceDate:s];
		float prog = (float) ((total - remain) / total);
		[progressView setProgress:prog];
		
		if ( ! displayRemaining )
		{
			NSDateFormatter* edf = [[NSDateFormatter alloc] init];
			[edf setDateFormat:@"MM-dd-yy HH:mm:ss"];	
			[endDateLabel setText:[edf stringFromDate:lf]];
			[edf release];		
		}
		else
		{
			long r = (long) remain;
			if ( r < 0 )
				r = 0;
			
			int days = r / 86400;
			r = r % 86400;
			int hours = r / 3600;
			r = r % 3600;
			int mins = r / 60;
			int secs = r % 60;
			
			[endDateLabel setText:[NSString stringWithFormat:@"%dd %dh %dm %ds", days, hours, mins, secs]];
		}
	}
}

- (void) reloadSkillData
{

	NSString* inTraining = (NSString*)[pilot.skillTrainingDict valueForKey:@"training"];
	if ( inTraining == nil )
	{
		trainingSkillLabel.text = [NSString stringWithString:@"No Skill Training"];
		progressView.progress = 0.0;
		endDateLabel.text = @"";
		return;
	}
	
	
	// Training Skill
	NSString* t = (NSString*)[pilot.skillTrainingDict valueForKey:@"typeID"];
	NSString* l = (NSString*)[pilot.skillTrainingDict valueForKey:@"toLevel"];
	if ( (t!=nil) && (l!=nil) )
	{
		NSString* sl;
		InventoryItem* skill = [EVEdb getItemWithKey:[t intValue]];
		
		if ( skill != nil )
		{
			sl = [NSString stringWithFormat:@"%@ %@", skill.typeName, l];
			[skill release];
		}
		else
			sl = [NSString stringWithFormat:@"Unknown Skill (%@) %@", t, l];

		trainingSkillLabel.text = sl;
	}
	
	// Training Skill time calculationss and display
	[self displayEndDate];
	
}

- (void) reloadData
{
	if ( pilot.needsReload )
		[self reloadHandler:self];
	else
	{		
		[self reloadPilotData];
		[self reloadSkillData];
	}
}
	

- (void) enableReloadButton
{
	[cancelButton setHidden:YES];
	[reloadButton setHidden:NO];
}

- (void) enableCancelButton
{
	[reloadButton setHidden:YES];
	[cancelButton setHidden:NO];
}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
	if ( [touches count] == 1 )
	{
		UITouch* touch = (UITouch*)[touches anyObject];

		if ( [touch view] == progressView )
		{
			displayRemaining = (displayRemaining) ? NO : YES;
			[self displayEndDate];
		}		
	}	
}



- (void) didReceiveMemoryWarning
{
}


- (void)dealloc 
{
	NSLog(@"%s %x", __FUNCTION__, self);
	
	WIPE( pilotPortrait)
	WIPE( pilotNameLabel)
	WIPE( corpLabel)
	WIPE( raceLabel)
	WIPE( iskiesValue)
	WIPE( iskiesHdr)
	WIPE( attValue)
	WIPE( attHdr)
	WIPE( skillpointsHdr)
	WIPE( skillpointsValue)
	WIPE( trainingSkillLabel)
	WIPE( endDateLabel)
	WIPE( progressView)
	WIPE( reloadButton)
	WIPE( cancelButton)
	WIPE( skillsDetailButton)
	WIPE( configButton)
//	WIPE( pilot)
	WIPE( eveRequestHandle)
	WIPE( eveSkillsHandle)
	WIPE( eveImgSvc)
	WIPE( parentVC)
	WIPE( rootPilotVC)
	WIPE( statusLine)
	
	[super dealloc];
}


@end
